Login dark

author: love02xp
title: VC 6.0下如何将汉字转换为utf-8网页转义编码
date: 2016-04-25 19:20:11
category: [编程代码]
tags: [学习,编程]


#####[阅读原文](http://bbs.csdn.net/topics/300120529)





在VC++ 6.0下要实现如下功能,将汉字转换为utf-8格式 和google类似 比如在google下搜索 "汉字",自动生成连接http://www.google.cn/search?hl=zh-CN&q=%E6%B1%89%E5%AD%97&meta=&aq=f&oq=  其中“%E6%B1%89%E5%AD%97”就是“汉字”的utf-8编码吧 我也想得到这样一串数据,在C++怎么实现呢?

<!--more-->
 

 

发表于: 2009-03-12 16:38:53 楼主 对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理 回复次数:14
csdn官网
csdn官网
官方推荐
Android设计模式学习之观察者模式 关注CSDN程序人生公众号,轻松获得下载积分 JavaEE 6及以上版本的web.xml问题? 大数据技术丛书《数据挖掘:实用案例分析》 Android 图片毛玻璃的实现方法 声卡采集 core audio api java+EE+API中文版 Halcyon数据库连接 目标检测和跟踪小结 如何将编码转换为UTF-8

hairetz
hairetz
猫已经找不回了  T9
 Blank  Blank  Blank 更多勋章
http://www.aghost.cn/blog/article.asp?id=145
这个你看如何?
回复于: 2009-03-12 17:14:58 #1 得分:15 对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理
akirya
akirya
珍惜生命远离CPP  T9
 Blank  Blank  Blank 更多勋章
这是转utf-8的,剩下的都容易
C/C++ code
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//LPCSTR pASCIIBuf 要转换的ascii字符串指针
//LPSTR pUtf8Buf=NULL  转换成Utf8编码的字符串指针
//返回值 如果pUtf8Buf为0 则返回需要pUtf8Buf长度
int AToUtf8(LPCSTR pASCIIBuf,LPSTR pUtf8Buf=NULL)
{
    if (NULL==pASCIIBuf)
        return 0;
    //    ZeroMemory( wch, sizeof(WCHAR)*RECV_BUF );
    DWORD  UniCodeLen=MultiByteToWideChar(CP_ACP, 0, pASCIIBuf, -1, 0, 0);
    AUTO_NEW(wch,unsigned short,UniCodeLen);
    MultiByteToWideChar(CP_ACP, 0, pASCIIBuf, -1, wch, UniCodeLen);
    DWORD dwUtf8Len=WideCharToMultiByte(CP_UTF8, 0, wch, UniCodeLen , NULL, NULL, NULL, NULL );
    if (NULL==pUtf8Buf)
        return dwUtf8Len;
    return WideCharToMultiByte(CP_UTF8, 0, wch, UniCodeLen , pUtf8Buf, dwUtf8Len, NULL, NULL );
}
回复于: 2009-03-12 17:18:25 #2 得分:35 对我有用[1] 丢个板砖[0] 引用 | 举报 | 管理
cnStreamlet
cnStreamlet
cnStreamlet  T3
C/C++ code
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
////////////////////////////////////////////////////////////////////////////////
//
//    文件名:    UTF8.cpp
//    作者:      溪流
//    创建时间:  2009-1-22 20:25:02
//    描述:      编码转换。暂时只有 Unicode 转为 UTF-8 的功能。
//
////////////////////////////////////////////////////////////////////////////////
 
#include "StdAfx.h"
#include "Encoding.h"
 
////////////////////////////////////////////////////////////////////////////////
 
// UTF-8 定义:
// U-00000000 - U-0000007F: 0xxxxxxx
// U-00000080 - U-000007FF: 110xxxxx 10xxxxxx
// U-00000800 - U-0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx
// (以下是 UCS-4 了)
// U-00010000 - U-001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
// U-00200000 - U-03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
// U-04000000 - U-7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
// 后面的 xxxx 用原来 Unicode 中的位依次填充
 
 
/// @brief Unicode 字符转换为 UTF-8 字符
/// @param buf [out] UTF-8 字符缓冲区,最大可能需要 6 个字节
/// @param bufSize buf 的大小,单位是字节
/// @param src [in] 源 Unicode 字符
/// @return 失败返回 -1,成功返回转换后 UTF-8 字符所占的字节数。
///         如果缓冲区过小(bufSize 指示),则返回需要的字节数。
int CEncoding::WCharToUTF8(char *buf, int bufSize, const wchar_t src)
{
    int bytesCount = 0;
 
    wchar_t firstByte;    // 从 Unicode 中取出二进制位作为 UTF-8 第一字节时的掩码
    char utfFirstByte;    // 为 UTF-8 第一字节加前导的若干个 1 要用的掩码
 
    wchar_t wTmp;
    char tmp;
     
    if (src == 0)
    {
        return -1;
    }
     
    if (src <= 0x7f)    // 01111111, ASCII
    {
        bytesCount = 1;
        firstByte = 0x7f;            // 0111 1111
        utfFirstByte = (BYTE)0x00;    // 0000 0000
    }
    else if (src <= 0x7ff)    // 1000 0000 - 0111 1111 1111,有效位数 11 位
    {
        bytesCount = 2;
        firstByte = 0x1f;            // 0001 1111,除去后一字节的 6 位,还剩 5 位
        utfFirstByte = (BYTE)0xc0;    // 1100 0000
    }
    else if (src <= 0xffff)    // 1000 0000 0000 - 1111 1111 1111 1111,16 位
    {
        bytesCount = 3;
        firstByte = 0x0f;            // 0000 1111,除去后两字节的 12 位,还剩 4 位
        utfFirstByte = (BYTE)0xe0;    // 1110 0000
    }
    // UCS-4 支持
    else if (src <= 0x001fffff)    // 计算方法下同,不再赘述
    {
        bytesCount = 4;
        firstByte = 0x07;
        utfFirstByte = (BYTE)0xf0;
    }
    else if (src <= 0x03ffffff)
    {
        bytesCount = 5;
        firstByte = 0x03;
        utfFirstByte = (BYTE)0xf8;
    }
    else if (src <= 0x7fffffff)
    {
        bytesCount = 6;
        firstByte = 0x01;
        utfFirstByte = (BYTE)0xfc;
    }
    // 提供的值不符合 Unicode 定义
    else
    {
        return -1;
    }
 
    if (bufSize >= bytesCount)
    {
        wTmp = src;
        for (int i = bytesCount - 1; i > 0; i--)    // 从低位往高位处理
        {
            tmp = (char)(wTmp & 0x3f);    // 取得低 6 位
            buf[i] = tmp | 0x80;    // 将最高 2 位变为 10
            wTmp >>= 6;
        }
 
        // 后面若干字节都处理完了,现在处理第一个字节
        tmp = (char)(wTmp & firstByte);    // 取出源字符中的剩余若干位
        buf[0] = (tmp | utfFirstByte);    // 高位或上若干个 1
    }
 
    return bytesCount;
}
 
/// @brief 字符转换为 UTF-8 字符
/// @param buf [out] UTF-8 字符串缓冲区
/// @param bufSize buf 的大小,单位是字节
/// @param src [in] 源 Unicode 字符串
/// @return 返回转换后 UTF-8 字符串所占的字节数。如果缓冲区过小(bufSize 指示),
///         那么仅转换到前 bufSize -1 个字节,第 bufSize 字节填零,返回 bufSize。
///         可以用根据返回值是否小于原来提供的 bufSize 来判断缓冲区是否足够大。
int CEncoding::WCharStringToUTF8(char *buf, int bufSize, wchar_t *src)
{
    int i = 0;
    while (*src != 0)
    {
        if (i >= bufSize)
        {
            buf[i - 1] = '\0';
            return i;
        }
 
        i += CEncoding::WCharToUTF8(buf + i, bufSize - i, *src++);
    }
 
    buf[i] = '\0';
 
    return i;
}
 
 
////////////////////////////////////////////////////////////////////////////////
回复于: 2009-03-12 20:19:39 #3 得分:35 对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理
cnStreamlet
cnStreamlet
cnStreamlet  T3
上面第一个函数是 Unicode 字符转 UTF-8 字符的,第二个函数是 Unicode 字符串转 UTF-8 字符串的
在程序中用 L'a'、L"12313" 就能得到 Unicode 的

之后对于 UTF-8 字符串中每一个字节,都用 16 进制输出,前面加上 % 就好了
回复于: 2009-03-12 20:23:54 #4 得分:15 对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理
qcbb001
qcbb001
大宝  T1
终于搞定了 不容易  楼上说的应该也可以实现 ,看下我的代码!




#include <string>
#include <stdio.h>
#include "windows.h"
// 把UTF-8转换成Unicode
void UTF_8ToUnicode(WCHAR* pOut,char *pText)
{
char* uchar = (char *)pOut;

uchar[1] = ((pText[0] & 0x0F) << 4) + ((pText[1] >> 2) & 0x0F);
uchar[0] = ((pText[1] & 0x03) << 6) + (pText[2] & 0x3F);

return;
}
// Unicode 转换成UTF-8 
void UnicodeToUTF_8(char* pOut,WCHAR* pText)
{
// 注意 WCHAR高低字的顺序,低字节在前,高字节在后
char* pchar = (char *)pText;

pOut[0] = (0xE0 | ((pchar[1] & 0xF0) >> 4));
pOut[1] = (0x80 | ((pchar[1] & 0x0F) << 2)) + ((pchar[0] & 0xC0) >> 6);
pOut[2] = (0x80 | (pchar[0] & 0x3F));

return;
}

// 把Unicode 转换成 GB2312 
void UnicodeToGB2312(char* pOut,unsigned short uData)
{
WideCharToMultiByte(CP_ACP,NULL,&uData,1,pOut,sizeof(WCHAR),NULL,NULL);
return;
}     

// GB2312 转换成 Unicode
void Gb2312ToUnicode(WCHAR* pOut,char *gbBuffer)
{
::MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,gbBuffer,2,pOut,1);
return;
}

//GB2312 转为 UTF-8
void GB2312ToUTF_8(CString& pOut,char *pText, int pLen)
{
char buf[1024];
char* rst = new char[pLen + (pLen >> 2) + 2];

memset(buf,0,1024);
memset(rst,0,pLen + (pLen >> 2) + 2);

int i = 0;
int j = 0;      
while(i < pLen)
{
//如果是英文直接复制就可以
if( *(pText + i) >= 0)
{
rst[j++] = pText[i++];
}
else
{
WCHAR pbuffer;
Gb2312ToUnicode(&pbuffer,pText+i);

UnicodeToUTF_8(buf,&pbuffer);

unsigned short int tmp = 0;
tmp = rst[j] = buf[0];
tmp = rst[j+1] = buf[1];
tmp = rst[j+2] = buf[2];


j += 3;
i += 2;
}
}
strcpy(&rst[j],"\0");

//返回结果
pOut = rst;             
delete []rst;   

return;
}

//UTF-8 转为 GB2312
void UTF_8ToGB2312(CString &pOut, char *pText, int pLen)
{
char * newBuf = new char[pLen];
char Ctemp[4];
memset(Ctemp,0,4);

int i =0;
int j = 0;

while(i < pLen)
{
if(pText[i] > 0)
{
newBuf[j++] = pText[i++];                       
}
else                 
{
WCHAR Wtemp;
UTF_8ToUnicode(&Wtemp,pText + i);

UnicodeToGB2312(Ctemp,Wtemp);

newBuf[j] = Ctemp[0];
newBuf[j + 1] = Ctemp[1];

i += 3;    
j += 2;   
}
}
strcpy(&newBuf[j],"\0");

pOut = newBuf;
delete []newBuf;

return; 
}


CString   UTF8_Encode(LPTSTR   strUnicode)   
{   
long   TLen   ;   
CString   UTF8_EncodeLong   ;   

TLen   =   CString(strUnicode).GetLength()   ;   

if(TLen   ==   0)   
{   
return   CString(strUnicode);   
}   

long   lngBufferSize   ;   
long   lngResult   ;   

//Set   buffer   for   longest   possible   string.   
lngBufferSize   =   TLen   *   3   +   1   ;   
char   *bytUtf8   =   new   char[lngBufferSize]   ;   

//Translate   using   code   page   65001(UTF-8).   

lngResult   =   WideCharToMultiByte(CP_UTF8,   0,   (unsigned   short*)strUnicode,   TLen,   bytUtf8,   lngBufferSize,   NULL,   0)   ;   

bytUtf8[lngResult]   =   NULL   ;   

return   CString(bytUtf8)   ;
}

/*************************************************************************/



CString URLEncode(CString sIn)
{
CString sOut; 
       const int nLen = sIn.GetLength() + 1;
register LPBYTE pOutTmp = NULL;
LPBYTE pOutBuf = NULL;
register LPBYTE pInTmp = NULL;
LPBYTE pInBuf =(LPBYTE)sIn.GetBuffer(nLen);
BYTE b = 0;
//alloc out buffer


pOutBuf = (LPBYTE)sOut.GetBuffer(nLen*3 - 2);//new BYTE [nLen  * 3];
if(pOutBuf)
{
pInTmp   = pInBuf;
pOutTmp = pOutBuf;
// do encoding


while (*pInTmp)
{
if(isalnum(*pInTmp))
*pOutTmp++ = *pInTmp;
else
if(isspace(*pInTmp))
*pOutTmp++ = '+';
else
//    if(*pInTmp<=127)
//     *pOutTmp++ = *pInTmp;
//    else
{
*pOutTmp++ = '%';

*pOutTmp++ = toHex(*pInTmp>>4);

*pOutTmp++ = toHex(*pInTmp%16);
}

pInTmp++;

}

*pOutTmp = '\0';

//sOut=pOutBuf;

//delete [] pOutBuf;

sOut.ReleaseBuffer();

}

sIn.ReleaseBuffer();

return sOut;

}
使用///////////////////////////////////

CString memname=“汉字";
GB2312ToUTF_8(memname,mem_name,TCBUFSIZE);
URLEncode(memname)便是所要的结果"“%E6%B1%89%E5%AD%97"了。

回复于: 2009-03-16 17:05:21 #5 得分:0 对我有用[1] 丢个板砖[0] 引用 | 举报 | 管理
aoxueqilin
aoxueqilin
aoxueqilin  T1
toHex 是什么函数啊?在这里好像缺少这个函数的定义。
回复于: 2009-03-18 11:53:48 #6 得分:0 对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理
aoxueqilin
aoxueqilin
aoxueqilin  T1
toHex 是什么函数啊?在这里好像缺少这个函数的定义。
回复于: 2009-03-18 12:47:55 #7 得分:0 对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理
qcbb001
qcbb001
大宝  T1
引用 6 楼 aoxueqilin 的回复:
toHex 是什么函数啊?在这里好像缺少这个函数的定义。


inline BYTE toHex(const BYTE &x)
{
return x > 9 ? x + 55: x + 48;
}

不好意思 没贴全!
更正下使用

使用/////////////////////////////////// 
char *mem_name = "汉字";
CString memname=“"; 
GB2312ToUTF_8(memname,mem_name,TCBUFSIZE); 
URLEncode(memname)便是所要的结果"“%E6%B1%89%E5%AD%97"了。 


回复于: 2009-03-19 09:12:09 #8 得分:0 对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理
xieyingfeichina
xieyingfeichina
xieyingfeichina  T1
非常好的示例,研究很深入啊,高手,太感谢了
回复于: 2010-07-21 10:28:25 #9 得分:0 对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理
silver307
silver307
silver307  T1
非常好的示例,研究很深入啊
回复于: 2010-09-06 11:07:47 #10 得分:0 对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理
windseeker2008
windseeker2008
windseeker2008  T1
好,学习了
回复于: 2010-11-25 10:01:34 #11 得分:0 对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理
liaochuan1234
liaochuan1234
liaochuan1234  T1
引用 2 楼 akirya 的回复:
这是转utf-8的,剩下的都容易
C/C++ code
//LPCSTR pASCIIBuf 要转换的ascii字符串指针
//LPSTR pUtf8Buf=NULL  转换成Utf8编码的字符串指针
//返回值 如果pUtf8Buf为0 则返回需要pUtf8Buf长度
int AToUtf8(LPCSTR pASCIIBuf,LPSTR pUtf8Buf=NULL)
{
    if (NU……


我用了可以